package com.example.dbscrew.api;

import com.example.dbscrew.service.DBService;
import com.example.dbscrew.util.ProgressUtil;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.stream.Collectors;

import static java.util.concurrent.Executors.newFixedThreadPool;

@RestController
@RequestMapping("/api")
public class DocumentController {

    @Resource
    private DBService dbService;

    // 缓存文档生成时间
    private final Map<String, String> docGenerationCache = new ConcurrentHashMap<>();

    private LocalDateTime lastGenerateTime;


    /**
     * 获取最后一次生成时间
     * @return
     */
    @GetMapping("/lastGenerateTime")
    public Map<String, String> getLastGenerateTime() {
        if (lastGenerateTime != null) {
            return Collections.singletonMap("lastGenerateTime", formatDateTime(lastGenerateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli()));
        } else {
            return Collections.emptyMap();
        }
    }

    @PostMapping("/generate")
    public ResponseEntity<Map<String, Object>> generateTableDocs() {
        if (isGenerating()) {
            return ResponseEntity.status(429).body(Collections.singletonMap("message", "已有生成任务在进行中"));
        }

        new Thread(() -> {
            docGenerationCache.put("status", "generating");
            try {
                doGenerate();
                lastGenerateTime = LocalDateTime.now();
            } finally {
                docGenerationCache.remove("status");
            }
        }).start();

        return ResponseEntity.accepted()
                .body(Collections.singletonMap("message", "生成任务已启动"));
    }

    private boolean isGenerating() {
        return docGenerationCache.containsKey("status");
    }

    @GetMapping("/documents")
    public List<String> getDocumentList() {
        File docDirectory = new File("doc/Markdown文件");
        if (!docDirectory.exists() || !docDirectory.isDirectory()) {
            return Collections.emptyList();
        }

        // 按照名称排序
        return Arrays.stream(docDirectory.listFiles(File::isFile))
                .sorted((f1, f2) -> Long.compare(f2.lastModified(), f1.lastModified()))
                .map(file -> file.getName()).sorted(Comparator.comparing(String::toLowerCase))
                .collect(Collectors.toList());
    }

    @GetMapping("/document/{filename}")
    public String getDocument(@PathVariable String filename) {
        File docFile = new File("doc/Markdown文件/" + filename);
        if (!docFile.exists() || !docFile.isFile()) {
            return "<h2>文档不存在</h2>";
        }

        try {
            String content = new String(Files.readAllBytes(docFile.toPath()), StandardCharsets.UTF_8);
            // 添加最后生成时间
            if (lastGenerateTime != null) {
                content = content.replace("**文档描述：** 数据库设计文档",
                        "**生成时间：** " + lastGenerateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            }
            return content;
        } catch (IOException e) {
            return "<h2>读取文档失败</h2><p>" + e.getMessage() + "</p>";
        }
    }

    private String formatDateTime(long timestamp) {
        return LocalDateTime.ofInstant(Instant.ofEpochMilli(timestamp), ZoneId.systemDefault())
                .format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"));
    }

    private void doGenerate() {
        try {
            List<String> dbTable = dbService.getDBTable();

            if (dbTable != null && !dbTable.isEmpty()) {
                int totalTables = dbTable.size();
                CountDownLatch latch = new CountDownLatch(totalTables);
                ExecutorService executor = newFixedThreadPool(20);

                for (String table : dbTable) {
                    String tableName = table;
                    executor.submit(() -> {
                        try {
                            dbService.generateTableDoc(tableName);
                        } catch (Exception e) {
                            System.err.println("Error generating table: " + tableName + " - " + e.getMessage());
                        } finally {
                            ProgressUtil.showProgress((int) (totalTables - latch.getCount() + 1), totalTables);
                            latch.countDown();
                        }
                    });
                }

                latch.await();
                executor.shutdown();
            }
        } catch (Exception e) {
            System.err.println("An error occurred: " + e.getMessage());
        }
    }


}
